package com.aliothservice.catfish.cart;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.aliothservice.catfish.SessionManager;
import com.aliothservice.catfish.cart.data.CartDataManager;
import com.aliothservice.catfish.cart.request.AddProductIntoCartRequest;
import com.aliothservice.catfish.cart.request.AddVehicleIntoCartRequest;
import com.aliothservice.catfish.cart.request.AddWarehouseIntoCartRequest;
import com.aliothservice.catfish.cart.request.DeleteServicesFromCartRequest;
import com.aliothservice.catfish.cart.request.MyCartCountingRequest;
import com.aliothservice.catfish.cart.request.MyCartRequest;
import com.aliothservice.catfish.product.data.ProductDataManager;
import com.aliothservice.catfish.product.data.ProductService;
import com.aliothservice.catfish.product.data.VehicleService;
import com.aliothservice.catfish.product.data.WarehouseService;

public class CartController {
	
	public Map<String, String> addWarehouseIntoCart(AddWarehouseIntoCartRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getWarehouseId()) || (null==req.getVolume()) || (null==req.getStartDate()) || (null==req.getUntilDate())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getVolume().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid volume");
			return map;
		}
		
		// validate warehouse service
		WarehouseService service = productDataManager.findWarehouseServiceById(req.getWarehouseId());
		if (null == service) {
			map.put("errorCode", "401");
			map.put("errorMessage", "service offline");
			return map;
		}
		if (service.getStock().intValue() < req.getVolume().intValue()) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not enough stock");
			return map;
		}
		if (0 == phoneNumber.compareTo(service.getUserId())) {
			Map<String, String> resMap = new HashMap<String, String>();
			resMap.put("errorCode", "410");
			resMap.put("errorMessage", "buy things you sell? you idiot!");
			return resMap;
		}
		
		// add into cart
		if (!cartDataManager.addWarehouseIntoCart(phoneNumber, req, service)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to add");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addProductIntoCart(AddProductIntoCartRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getProductId()) || (null==req.getVolume())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (0 > req.getVolume().intValue()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - invalid volume");
			return map;
		}
		
		// validate product service
		ProductService service = productDataManager.findProductServiceById(req.getProductId());
		if (null == service) {
			map.put("errorCode", "401");
			map.put("errorMessage", "service offline");
			return map;
		}
		if (service.getStock().intValue() < req.getVolume().intValue()) {
			map.put("errorCode", "402");
			map.put("errorMessage", "not enough stock");
			return map;
		}
		if (0 == phoneNumber.compareTo(service.getUserId())) {
			Map<String, String> resMap = new HashMap<String, String>();
			resMap.put("errorCode", "410");
			resMap.put("errorMessage", "buy things you sell? you idiot!");
			return resMap;
		}
		
		// add into cart
		if (!cartDataManager.addProductIntoCart(phoneNumber, req, service)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to add");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> addVehicleIntoCart(AddVehicleIntoCartRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if ((null==req.getVehicleId()) || (null==req.getTemperatureSpec()) || (null==req.getLoadingDate())) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		
		// validate vehicle service
		VehicleService service = productDataManager.findVehicleServiceById(req.getVehicleId());
		if (null == service) {
			map.put("errorCode", "401");
			map.put("errorMessage", "service offline");
			return map;
		}
		logger.debug("phone number - " + phoneNumber);
		if (0 == phoneNumber.compareTo(service.getUserId())) {
			Map<String, String> resMap = new HashMap<String, String>();
			resMap.put("errorCode", "410");
			resMap.put("errorMessage", "buy things you sell? you idiot!");
			return resMap;
		}
		
		// add into cart
		if (!cartDataManager.addVehicleIntoCart(phoneNumber, req, service)) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to add");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Object myCart(MyCartRequest req) {
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		return cartDataManager.myCart(phoneNumber);
	}
	
	public Map<String, String> deleteServicesFromCart(DeleteServicesFromCartRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// validate parameters
		if (null == req.getIdList()) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters");
			return map;
		}
		if (req.getIdList().size() <= 0) {
			map.put("errorCode", "400");
			map.put("errorMessage", "missing parameters - empty request");
			return map;
		}
		logger.info("deleteServicesFromCart - " + phoneNumber + " will delete " + req.getIdList().toString());
		
		// perform deletion
		if (!cartDataManager.deleteServicesFromCart(phoneNumber, req.getIdList())) {
			map.put("errorCode", "500");
			map.put("errorMessage", "failed to delete");
			return map;
		}
		
		// reset token expiration
		sessionManager.resetRestTokenExpiration(phoneNumber, req.getToken());
		
		return map;
	}
	
	public Map<String, String> myCartCounting(MyCartCountingRequest req) {
		Map<String, String> map = new HashMap<String, String>();
		
		// validate token
		String phoneNumber = (String)sessionManager.valueForRestToken(req.getToken());
		if (null == phoneNumber) {
			map.put("errorCode", "300");
			map.put("errorMessage", "token expired");
			return map;
		}
		
		// fill up response
		cartDataManager.myCartCounting(phoneNumber, map);

		return map;
	}

	@Autowired
	private SessionManager sessionManager;
	
	@Autowired
	private CartDataManager cartDataManager;
	
	@Autowired
	private ProductDataManager productDataManager;
	
	private static final Logger logger = LoggerFactory.getLogger(CartController.class);
}
